iT邦幫忙

2021 iThome 鐵人賽

DAY 2
0
Software Development

猴子都寫得出來的 RISC-V CPU Emulator系列 第 12

RISC-V: I-type 小於指令

  • 分享至 

  • xImage
  •  

本來因為 RISC-V 指令規格書寫明 imm 全部都是 Sign Extended,
決定全部都用 imm 表示,
寫到一半發現這次的指令單純寫 imm 會不好理解,
稍微修改格式為 SignExt-imm。

I-type

指令格式如下:

|31     20|19   15|14    12|11   7|6       0|
+-------------------------------------------+
|   imm   |  rs1  | funct3 |  rd  | pocode  |
+-------------------------------------------+

SLTI

rd = rs1 < SignExt-imm ? 1 : 0

|31     20|19   15|14    12|11   7|6       0|
+-------------------------------------------+
|   imm   |  rs1  |  010   |  rd  | 0010011 |
+-------------------------------------------+

SLTIU

這邊是將 imm 拿出來 Sign Extension 後,
再當作 unsigned 跟 rs1 比。
rd = rs1 < (uint32_t) SignExt-imm ? 1 : 0

|31     20|19   15|14    12|11   7|6       0|
+-------------------------------------------+
|   imm   |  rs1  |  011   |  rd  | 0010011 |
+-------------------------------------------+

SEQZ

這道指令也是跟 SLTIU 一樣,
只是將 imm 值設定為 1,
這時候小於 1 的就只能是 0 了。
rd = rs1 < (uint32_t) 1 ? 1 : 0
= (rs1 == 0) ? 1 : 0

|31     20|19   15|14    12|11   7|6       0|
+-------------------------------------------+
|    1    |  rs1  |  011   |  rd  | 0010011 |
+-------------------------------------------+

實際程式

github 頁面 Tag: ITDay12
大家有猜到昨天說的 bug 是什麼嗎?
就是 Immediate 沒有 Sign Extension 拉!
所以執行結果的第二道指令 1 + (-1)運算出來的值才會是 4096,而不是0。

可能是因為不夠熟悉,找來找去沒在 SystemC 找到相關的功能,
只好自己做。
知道的夥伴可以歡迎留言告訴我!

//instructionDecoder.cpp
int32_t INSTRUCTION_DECODER::get_imm(uint32_t end, uint32_t start)
{
	return sc_dt::sc_int<32>(instruction_value) << (31-end) >> start;
}
//instructionDecoderInterface.h
...
		SLTI_FN3 = 0b010,
		SLTIU_FN3 = 0b011,
...

兩道指令唯一的差別只 SLTIU 多了 int 轉為 uint 的轉型而已,
這邊因為型別很單純,為了可讀性使用 c style 轉型,
而不使用 static_cast<uint32_t>。

//executor.cpp
...
				case INSTRUCTION_DECODER_INTERFACE::SLTI_FN3:
					SLTI_E();
					break;
				case INSTRUCTION_DECODER_INTERFACE::SLTIU_FN3:
					SLTIU_E();
					break;
...
void EXECUTOR::SLTI_E()
{
	auto rs1 = instruction_decoder->get_rs1();
	auto rd = instruction_decoder->get_rd();

	auto value = register_file->get_value_integer(rs1) < instruction_decoder->get_imm(31, 20);
	register_file->set_value_integer(rd, value);
...
}

void EXECUTOR::SLTIU_E()
{
	auto rs1 = instruction_decoder->get_rs1();
	auto rd = instruction_decoder->get_rd();

	auto value = register_file->get_value_integer(rs1) < (uint32_t) instruction_decoder->get_imm(31, 20);
	register_file->set_value_integer(rd, value);
...
}

執行結果

$ make run
./simulator

        SystemC 2.3.3-Accellera --- Sep 17 2021 22:09:07
        Copyright (c) 1996-2018 by all Contributors,
        ALL RIGHTS RESERVED
ADDI
rs1: 0
rd: 1
value: 1
ADDI
rs1: 1
rd: 2
value: 0
ADDI
rs1: 0
rd: 0
value: 0
SLTI
rs1: 0
rd: 0
value: 0
SLTIU
rs1: 0
rd: 0
value: 1


上一篇
RISC-V: I-type 位元運算指令
下一篇
RISC-V: I-type 移位指令
系列文
猴子都寫得出來的 RISC-V CPU Emulator31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言